const express = require('express');
const bodyParser = require('body-parser');
const session = require('express-session');
const fs = require('fs');
const path = require('path');
const app = express();
const port = 3000;

// 定义数据文件路径
const DATA_DIR = path.join(__dirname, 'data');
const BOOKINGS_FILE = path.join(DATA_DIR, 'bookings.json');
const USERS_FILE = path.join(DATA_DIR, 'users.json');
const RESOURCES_FILE = path.join(DATA_DIR, 'resources.json');

// 确保数据目录存在
if (!fs.existsSync(DATA_DIR)) {
    fs.mkdirSync(DATA_DIR);
}

// 从文件加载数据
function loadData() {
    try {
        if (fs.existsSync(RESOURCES_FILE)) {
            const resourcesData = JSON.parse(fs.readFileSync(RESOURCES_FILE, 'utf8'));
            resources = resourcesData.resources;
            nextResourceId = resourcesData.nextResourceId;
        }

        if (fs.existsSync(BOOKINGS_FILE)) {
            bookings = JSON.parse(fs.readFileSync(BOOKINGS_FILE, 'utf8'));
            // 恢复 nextId，设置为当前最大 id + 1
            nextId = Math.max(...bookings.map(b => b.id), 0) + 1;
        }
        if (fs.existsSync(USERS_FILE)) {
            users = JSON.parse(fs.readFileSync(USERS_FILE, 'utf8'));
            // 兼容旧数据：如果role是admin但缺少isAdmin字段
            users = users.map(user => {
                if (user.role === 'admin' && !user.hasOwnProperty('isAdmin')) {
                    return { ...user, isAdmin: true };
                }
                return user;
            });
        }
    } catch (err) {
        console.error('Error loading data:', err);
    }
}

// 保存数据到文件
function saveData() {
    try {
        fs.writeFileSync(BOOKINGS_FILE, JSON.stringify(bookings, null, 2));
        fs.writeFileSync(USERS_FILE, JSON.stringify(users, null, 2));
        fs.writeFileSync(RESOURCES_FILE, JSON.stringify({
            resources,
            nextResourceId
        }, null, 2));
    } catch (err) {
        console.error('Error saving data:', err);
    }
}

// 中间件
app.use(bodyParser.json());
app.use(session({
  secret: 'your-secret-key', // 请替换成一个安全的密钥
  resave: false,
  saveUninitialized: true,
  cookie: { secure: false } // 开发时设为 false，生产环境如果使用 HTTPS 则改为 true
}));
app.use(express.static('public'));

// 内存中保存预订记录
let bookings = [];
let nextId = 1;

// 内存中保存用户数据（演示用，实际环境中请使用数据库）
let users = [];

// 内存中保存资源数据
let resources = [];
let nextResourceId = 1;

// 启动时加载数据
loadData();

// 辅助方法：判断两个时间区间是否重叠
function isOverlapping(start1, end1, start2, end2) {
    return start1 < end2 && start2 < end1;
}

// GET /api/bookings
// 可接收 ?start=&end= 两个查询参数以过滤出指定时间段的预订，比如当前和下一周
app.get('/api/bookings', (req, res) => {
    const { start, end } = req.query;
    let result = bookings;
    if (start && end) {
        const filterStart = new Date(start);
        const filterEnd = new Date(end);
        result = result.filter(b => {
            const bStart = new Date(b.start);
            const bEnd = new Date(b.end);
            // 如果预订与筛选时间段有重合则返回
            return bEnd > filterStart && bStart < filterEnd;
        });
    }
    res.json(result);
});

// POST /api/bookings
// 新建预订只需要提供 { start, end }，当前登录用户从 session 中读取
app.post('/api/bookings', (req, res) => {
    if (!req.session.user) {
        return res.status(403).json({ message: '请先登录.' });
    }
    const { start, end, resourceId } = req.body;
    const startTime = new Date(start);
    const endTime = new Date(end);

    // 验证时间格式
    if (isNaN(startTime.getTime()) || isNaN(endTime.getTime())) {
        return res.status(400).json({ message: '无效的时间格式.' });
    }

    // 验证时间顺序
    if (startTime >= endTime) {
        return res.status(400).json({ message: '开始时间必须早于结束时间.' });
    }

    // 验证最小时间间隔（10分钟）
    if (endTime - startTime < 10 * 60 * 1000) {
        return res.status(400).json({ message: '预订时间必须至少10分钟.' });
    }

    // 验证资源存在
    const resourceExists = resources.some(r => r.id === resourceId);
    if (!resourceExists) {
        return res.status(400).json({ message: '无效的资源ID' });
    }

    // 检查时间重叠
    const hasOverlap = bookings.some(booking => {
        const existingStart = new Date(booking.start);
        const existingEnd = new Date(booking.end);
        return startTime < existingEnd && existingStart < endTime;
    });

    if (hasOverlap) {
        return res.status(400).json({ message: '该时间段已被预订.' });
    }

    // 检查时间重叠时加入资源过滤
    const hasOverlapWithResource = bookings.some(booking => 
        booking.resourceId === resourceId && 
        startTime < new Date(booking.end) && 
        new Date(booking.start) < endTime
    );

    if (hasOverlapWithResource) {
        return res.status(400).json({ message: '该时间段已被预订.' });
    }

    // 创建新预订
    const booking = {
        id: nextId++,
        user: req.session.user.username,
        start: startTime.toISOString(),
        end: endTime.toISOString(),
        resourceId: resourceId
    };

    bookings.push(booking);
    saveData();

    res.json(booking);
});

// DELETE /api/bookings/:id
// 删除预订时仅允许当前登录用户操作
app.delete('/api/bookings/:id', (req, res) => {
    if (!req.session.user) {
        return res.status(403).json({ message: '请先登录.' });
    }
    const user = req.session.user.username;
    const id = parseInt(req.params.id);
    const bookingIndex = bookings.findIndex(b => b.id === id);
    if (bookingIndex === -1) {
        return res.status(404).json({ message: 'Booking not found.' });
    }
    const booking = bookings[bookingIndex];
    if (booking.user !== user) {
        return res.status(403).json({ message: 'You can only delete your own bookings.' });
    }
    bookings.splice(bookingIndex, 1);
    saveData(); // 保存更新后的预订数据
    res.json({ message: 'Booking deleted.' });
});

// PUT /api/bookings/:id
app.put('/api/bookings/:id', (req, res) => {
    if (!req.session.user) {
        return res.status(403).json({ message: '请先登录.' });
    }
    const user = req.session.user.username;
    const id = parseInt(req.params.id);
    const { start, end } = req.body;
    
    const bookingIndex = bookings.findIndex(b => b.id === id);
    if (bookingIndex === -1) {
        return res.status(404).json({ message: 'Booking not found.' });
    }
    
    const booking = bookings[bookingIndex];
    if (booking.user !== user) {
        return res.status(403).json({ message: 'You can only update your own bookings.' });
    }
    
    const startTime = new Date(start);
    const endTime = new Date(end);
    
    // 验证新的时间段
    if (isNaN(startTime.getTime()) || isNaN(endTime.getTime())) {
        return res.status(400).json({ message: 'Invalid date format.' });
    }
    if (startTime >= endTime) {
        return res.status(400).json({ message: 'Start time must be before end time.' });
    }
    
    // 检查时间重叠（排除当前预订）
    for (let b of bookings) {
        if (b.id !== id) {
            const existingStart = new Date(b.start);
            const existingEnd = new Date(b.end);
            if (isOverlapping(startTime, endTime, existingStart, existingEnd)) {
                return res.status(400).json({ message: 'Time slot already booked.' });
            }
        }
    }
    
    booking.start = startTime.toISOString();
    booking.end = endTime.toISOString();
    saveData();
    
    res.json(booking);
});

// 用户注册
app.post('/api/register', (req, res) => {
    const { username, password } = req.body;
    if (!username || !password) {
        return res.status(400).json({ message: '用户名和密码均不能为空.' });
    }
    if (users.find(u => u.username === username)) {
        return res.status(400).json({ message: '用户名已存在.' });
    }
    const newUser = { username, password, role: 'user' };
    users.push(newUser);
    saveData(); // 保存更新后的用户数据
    return res.json({ message: '注册成功.' });
});

// 用户登录
app.post('/api/login', (req, res) => {
    const { username, password } = req.body;
    const user = users.find(u => u.username === username && u.password === password);
    if (!user) {
        return res.status(401).json({ message: '用户名或密码错误.' });
    }
    req.session.user = { 
        username: user.username, 
        role: user.role,
        isAdmin: user.role === 'admin' || user.isAdmin === true 
    };
    return res.json({ message: '登录成功.', user: req.session.user });
});

// 获取当前用户
app.get('/api/currentUser', (req, res) => {
    if (req.session.user) {
        res.json({ user: req.session.user });
    } else {
        res.json({ user: null });
    }
});

// 登出
app.post('/api/logout', (req, res) => {
    req.session.destroy(() => {
        res.json({ message: '已登出.' });
    });
});

// 获取所有资源
app.get('/api/resources', (req, res) => {
  res.json(resources);
});

// 创建新资源（仅管理员）
app.post('/api/resources', (req, res) => {
  if (!req.session.user?.isAdmin) {
    return res.status(403).json({ message: '需要管理员权限' });
  }
  const { name, description } = req.body;
  const newResource = {
    id: nextResourceId++,
    name,
    description: description || ''
  };
  resources.push(newResource);
  saveData();
  res.json(newResource);
});

// 删除资源（仅管理员）
app.delete('/api/resources/:id', (req, res) => {
  if (!req.session.user?.isAdmin) {
    return res.status(403).json({ message: '需要管理员权限' });
  }
  const id = parseInt(req.params.id);
  resources = resources.filter(r => r.id !== id);
  saveData();
  res.json({ success: true });
});

app.listen(port, () => {
    console.log(`Server is running on port ${port}`);
}); 